package cate.game.activity.specall;

import cate.common.table.activity.base.ShopActivityBaseRow;
import cate.common.table.activity.specall.row.SpeCallStarRow;
import cate.common.table.d.GDActivity;
import cate.common.table.d.GDOperation;
import cate.common.table.item.hero.row.HeroBaseRow;
import cate.common.table.pay.PayItemRow;
import cate.common.util.GameResult;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.bag.hero.Hero;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SpeCallGlobalData extends RoleDependent {
    @NoteField(value = "升星专属免费奖励领取记录")
    public List<Integer> getRecords;
    @NoteField(value = "限购数量记录")
    public Map<Integer, Integer> buyRecords;
    @NoteField(value = "玩家能获取的礼包")
    public Map<Integer, Boolean> availableGet;

    @Override
    public void initialize(Role role){
        super.initialize(role);
        if (getRecords == null) {
            getRecords = new ArrayList<>();
        }
        if (buyRecords == null) {
            buyRecords = new HashMap<>();
        }
        if (availableGet == null) {
            availableGet = new HashMap<>();
        }
    }

    public synchronized void openGift() {
        Map<Integer, Integer> protoAndStar = new HashMap<>();
        List<Hero> heroes = role.getBag().hero.getList();
        for (Hero hero : heroes) {
            if (availableGet.containsKey(hero.tid)) {
                HeroBaseRow tpl = hero.getTpl(role.getGame());
                protoAndStar.compute(tpl.protoId, (k, v) -> {
                    if (!protoAndStar.containsKey(k)) {
                        return tpl.star;
                    }
                    if (protoAndStar.containsKey(k) && tpl.star > v) {
                        return tpl.star;
                    }
                    return v;
                });
            }
        }
        for (Integer tid : availableGet.keySet()) {
            HeroBaseRow row = role.getGame().table.hero.base.get(tid);
            if (row != null && protoAndStar.get(row.protoId) != null && row.star <= protoAndStar.get(row.protoId)) {
                availableGet.put(tid, true);
            }
        }
    }

    public boolean updateAvailable(String uid) {
        boolean change = false;
        Hero item = role.getBag().hero.getItem(uid);
        if (availableGet.containsKey(item.tid) && Boolean.TRUE.equals(availableGet.get(item.tid))) {
            return change;
        }
        for (Integer key : availableGet.keySet()) {
            SpeCallStarRow row = getConfig(key);
            if (row == null) {
                continue;
            }
            if (availableGet.containsKey(item.tid)) {
                availableGet.put(item.tid, true);
                change = true;
                break;
            }
        }
        return change;
    }

    private SpeCallStarRow getConfig(int tid) {
        return role.getGame().table.speCall.star.get(tid);
    }

    public GameResult<Void> allowPay(PayItemRow pir) {
        GameResult<Void> r = new GameResult<>();
        int tid = pir.funcSubId;
        if (!buyRecords.containsKey(tid)) {
            return r.fail("未找到配置1");
        }
        SpeCallStarRow config = getConfig(tid);
        if (config == null) {
            return r.fail("未找到配置2");
        }
        if (Boolean.FALSE.equals(availableGet.getOrDefault(tid, false))) {
            return r.fail("无购买此奖励资格");
        }
        if (config.limitTimes != -1 && buyRecords.get(tid) + 1 > config.limitTimes) {
            return r.fail("限购次数不足");
        }
        if (config.buyType != ShopActivityBaseRow.SHOP_TYPE_PAY) {
            return r.fail("不支持此购买模式");
        }
        return r.success();
    }

    public void onPaySuccess(PayItemRow payItemRow) {
        SpeCallStarRow config = getConfig(payItemRow.funcSubId);
        if (config == null) {
            return;
        }
        MixRes reward = new MixRes(config.payRewardStr);
        reward.add(role, true, GDOperation.SPE_STAR_GIFT_BUY, payItemRow.funcSubId);
        buyRecords.compute(payItemRow.funcSubId, (k, v) -> v + 1);
        role.getGame().notice.dialogReward(role, reward);
    }

    public void excelCheck(List<Integer> allConfigs) {
        if (allConfigs.isEmpty()) {
            return;
        }
        for (Integer tid : allConfigs) {
            if (!buyRecords.containsKey(tid)) {
                buyRecords.put(tid, 0);
            }
            if (!availableGet.containsKey(tid)) {
                availableGet.put(tid, false);
            }
        }
    }

    public EcResult<Void> getReward(int tid) {
        EcResult<Void> r = new EcResult<>();
        SpeCallStarRow config = getConfig(tid);
        if (config == null) {
            return r.fail("未找到此奖励配置");
        }
        if (getRecords.contains(tid)) {
            return r.fail("已领取过该奖励");
        }
        if (Boolean.FALSE.equals(availableGet.getOrDefault(tid, false))) {
            return r.fail("无领取该奖励资格");
        }
        MixRes rewardRes = new MixRes(config.freeRewardStr);
        if (rewardRes.isEmpty()) {
            return r.fail("奖励为空");
        }
        rewardRes.add(role, true, 0, tid);
        getRecords.add(tid);
        role.getGame().notice.dialogReward(role, rewardRes);
        return r.success();
    }

    public EcResult<Void> buyItem(int tid, int num) {
        EcResult<Void> r = new EcResult<>();
        if (!buyRecords.containsKey(tid)) {
            return r.fail("未找到配置1");
        }
        SpeCallStarRow config = getConfig(tid);
        if (config == null) {
            return r.fail("未找到配置2");
        }
        if (Boolean.FALSE.equals(availableGet.getOrDefault(tid, false))) {
            return r.fail("无购买此奖励资格");
        }
        if (config.limitTimes != -1) {
            if (buyRecords.get(tid) > config.limitTimes - num) {
                return r.fail("限购次数不足");
            }
        }
        if (config.buyType != GDActivity.SHOP_TYPE_ITEM_COST) {
            return r.fail("不支持此购买模式");
        }
        MixRes reward = new MixRes(config.freeRewardStr);
        if (reward.isEmpty()) {
            return r.fail("奖励为空");
        }
        MixRes costRes = new MixRes(config.consumeStr);
        if (!costRes.isEmpty()) {
            EcResult<MixResItem> consumeRes = costRes.multiply(num).consume(role, null);
            if (!consumeRes.ok()) {
                role.getGame().notice.tipResItem(role, consumeRes.data);
                return r.fail(consumeRes.message);
            }
        }
        reward.multiply(num).add(role, true);
        buyRecords.compute(tid, (k, v) -> v + num);
        return r.success();
    }
}
